package com.taxi.driver.module.main.duty;

import com.alibaba.fastjson.JSON;
import com.amap.api.maps.model.LatLng;
import com.qianxx.utils.RxUtil;
import com.socks.library.KLog;
import com.taxi.driver.R;
import com.taxi.driver.common.BasePresenter;
import com.taxi.driver.config.BizStatus;
import com.taxi.driver.config.DutyStatus;
import com.taxi.driver.config.PositionType;
import com.taxi.driver.data.amap.AMapManager;
import com.taxi.driver.data.duty.DutyRepository;
import com.taxi.driver.data.order.OrderRepository;
import com.taxi.driver.data.user.UserRepository;
import com.taxi.driver.event.NetworkEvent;
import com.taxi.driver.event.OrderEvent;
import com.taxi.driver.socket.SocketData;
import com.taxi.driver.socket.SocketEvent;
import com.taxi.driver.socket.SocketPushContent;
import com.taxi.driver.socket.message.UploadLocationMessage;
import com.taxi.driver.socket.message.base.MessageType;
import com.taxi.driver.util.ScreenUtil;
import com.taxi.driver.util.SpeechUtil;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import javax.inject.Inject;

import rx.Observable;
import rx.Subscription;

/**
 * 功能描述：
 */
public class DutyPresenter extends BasePresenter implements DutyContract.Presenter {

    private final AMapManager mAMapManager;

    private DutyContract.View mView;
    private DutyRepository mDutyRepository;
    private OrderRepository mOrderRepository;
    private UserRepository mUserRepository;

    private boolean isFront = false;
    private boolean isNoOrder = true;
    private boolean isComplete = true;
    private boolean isOnDuty = true;
    // 司机当前坐标
    private LatLng mLatLng;
    private Subscription mSubscribe;

    private List<SocketData> mOrderList = new ArrayList<>();
    private Subscription mTimer;

    @Inject
    public DutyPresenter(DutyContract.View view, DutyRepository dutyRepository,
                         OrderRepository orderRepository, UserRepository userRepository,
                         AMapManager aMapManager) {
        mView = view;
        mDutyRepository = dutyRepository;
        mOrderRepository = orderRepository;
        mUserRepository = userRepository;
        mAMapManager = aMapManager;
    }

    @Override
    public void subscribe() {
        super.subscribe();

        isFront = true;

        if (isComplete) {
            mTimer = Observable.timer(2, TimeUnit.SECONDS)
                    .compose(RxUtil.applySchedulers())
                    .subscribe(aLong -> {
                        if (!mOrderList.isEmpty()) {
                            mView.openOrderPopup(mOrderList.get(0).orderUuid, false);
                            mOrderList.remove(0);
                        } else {
                            isNoOrder = true;
                        }
                    }, KLog::e);
        }
    }

    @Override
    public void unsubscribe() {
        super.unsubscribe();

        isFront = false;

        if (mTimer != null && mTimer.isUnsubscribed()) {
            mTimer.unsubscribe();
        }
    }

    @Override
    public void reqDutyStatus() {
        mSubscriptions.add(
                mDutyRepository.reqDutyStatus(true)
                        .compose(RxUtil.applySchedulers())
                        .subscribe(s -> {
                            if (DutyStatus.ON_DUTY.equals(s)) {
                                isOnDuty = true;
                                mView.showOnDuty();
                                EventBus.getDefault().post(new SocketEvent(SocketEvent.WORKING_STATUS, true));
                            } else {
                                isOnDuty = false;
                                mView.showOffDuty();
                                EventBus.getDefault().post(new SocketEvent(SocketEvent.WORKING_STATUS, false));
                            }
                        }, KLog::e));
    }

    @Override
    public void reqOnduty() {
        SpeechUtil.speech(mView.getContext(), "开始接单");
        mSubscribe = Observable.timer(4, TimeUnit.SECONDS)
                .compose(RxUtil.applySchedulers())
                .doOnSubscribe(() -> {
                    KLog.e("------------bbbbb---------");
                    EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.EMPTY_DRIVING, PositionType.SJSB));
                    mView.showDuty();

                })
                .subscribe(aLong -> onDuty(), ex -> {
                    mView.showOffDuty();

                    toast("出车失败，请稍后再试");
                });
    }

    private void onDuty() {
        KLog.e("------------aaaaa---------");
        mLatLng = new LatLng(mAMapManager.getLastLocation().getLatitude(), mAMapManager.getLastLocation().getLongitude());
        String uploadText = uploadText(BizStatus.EMPTY_DRIVING, mLatLng, PositionType.SJSB);

        mSubscriptions.add(
                mDutyRepository.reqOnDuty(mLatLng.longitude, mLatLng.latitude, uploadText)
                        .compose(RxUtil.applySchedulers())
                        .subscribe(s -> {
                            isOnDuty = true;
                            mView.showOnDuty();
//                            SpeechUtil.speech(mView.getContext(), "开始接单");
                        }, ex -> {
                            showNetworkError(ex, R.string.network_error, mView, mUserRepository);
                            mView.showOffDuty();
                        }));
    }

    @Override
    public void reqOffduty() {
//        SpeechUtil.stop(mView.getContext());
        SpeechUtil.speech(mView.getContext(), "停止接单");
        mLatLng = new LatLng(mAMapManager.getLastLocation().getLatitude(), mAMapManager.getLastLocation().getLongitude());
        String uploadText = uploadText(BizStatus.STOP_BUSINESS, mLatLng, PositionType.SJXB);

        mSubscriptions.add(
                mDutyRepository.reqOffDuty(mLatLng.longitude, mLatLng.latitude, uploadText)
                        .compose(RxUtil.applySchedulers())
                        .doOnNext(s -> {
                            // 发送司机位置（司机下班）
                            EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.STOP_BUSINESS, PositionType.SJXB));
                        })
                        .subscribe(s -> {
                            isOnDuty = false;
                            mView.showOffDuty();
//                            SpeechUtil.speech(mView.getContext(), "停止接单");
                        }, ex -> showNetworkError(ex, R.string.network_error, mView, mUserRepository)));
    }

    private String uploadText(int bizStatus, LatLng latLng, String positionType) {
        UploadLocationMessage uploadLocationMessage = new UploadLocationMessage();
        uploadLocationMessage.setAppid(mView.getContext().getString(R.string.yueyue_appkey));
        uploadLocationMessage.setBizStatus(bizStatus);
        uploadLocationMessage.setAreaCode(mAMapManager.getLastLocation().getAdCode());
        uploadLocationMessage.setDriverType(mUserRepository.getDriverType());
        uploadLocationMessage.setLat(latLng.latitude);
        uploadLocationMessage.setLng(latLng.longitude);
        uploadLocationMessage.setPositionType(positionType);
        uploadLocationMessage.setDistance(0d);
        uploadLocationMessage.setCarLevelType(mUserRepository.getCarLevelType());
        uploadLocationMessage.setClientUuid(mUserRepository.getLocalDriverUuid());
        uploadLocationMessage.setDriverUuid(mUserRepository.getLocalDriverUuid());
        uploadLocationMessage.setLocationUuid(System.currentTimeMillis() + "");
        uploadLocationMessage.setType(MessageType.UPLOAD_LOCATION);
        return JSON.toJSONString(uploadLocationMessage);
    }

    @Override
    public void reqOrderDetail(String orderUuid, boolean isAssign) {
        if (!isMatchCondition()) return;

        isNoOrder = false;
        /* 先判断是否已出车，再执行获取订单详情的操作 */
        mSubscriptions.add(
                mDutyRepository.reqDutyStatus(false)
                        .compose(RxUtil.applySchedulers())
                        .flatMap(s -> {
                            if (DutyStatus.ON_DUTY.equals(s)) {
                                return mOrderRepository.reqOrderDetail(orderUuid, true).compose(RxUtil.applySchedulers());
                            } else {
                                return Observable.empty();
                            }
                        })
                        .subscribe(entity -> mView.openOrderPopup(entity.uuid, isAssign),
                                KLog::e));
    }

    /**
     * 判断当前应用是否处于后台，并且没有正在行程中的订单，同时处于听单界面
     * 是否符合条件：true－符合条件，弹出订单、false－不符合条件，不弹出
     *
     * @return
     */
    private boolean isMatchCondition() {
        return ((isFront || ScreenUtil.isBackground(mView.getContext())));
    }

    public void onCreate() {
        EventBus.getDefault().register(this);
    }

    public void onDestory() {
        EventBus.getDefault().unregister(this);
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onOrderEvent(OrderEvent event) {
        switch (event.type) {
            case OrderEvent.ORDER_PUSH: {
                //收到推送订单，先获取订单详情
                if (event.obj1 == null) return;
                if (!isComplete) return;
                if (!isOnDuty) return;
                SocketPushContent push = (SocketPushContent) event.obj1;
                mOrderRepository.ignoreList()
                        .filter(strings -> {
                            for (String string : strings) {
                                if (string.equals(push.orderUuid)) {
                                    return null;
                                }
                            }
                            return true;
                        })
                        .compose(RxUtil.applySchedulers())
                        .subscribe(KLog::e, KLog::e, () -> {
                            if (isNoOrder) {
                                reqOrderDetail(push.orderUuid, false);
                            } else {
                                mOrderList.add(0, push.data);
                            }
                        });
                break;
            }
            case OrderEvent.ORDER_CHANGE_DISTRIBUTE://收到改派订单
            case OrderEvent.ORDER_DISTRIBUTE://收到指派订单
                if (event.obj1 == null) return;
                SocketPushContent distribute = (SocketPushContent) event.obj1;
                reqOrderDetail(distribute.orderUuid, true);
                // 发送司机位置（收到派单）
                EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.ORDER_RECEIVING, PositionType.DDPD, distribute.orderUuid));
                // 发送司机位置（司机出发）
                EventBus.getDefault().post(new SocketEvent(SocketEvent.SEND_POSITION, BizStatus.CARRY_PASSENGERS, PositionType.SJCF, distribute.orderUuid));
                break;
            case OrderEvent.ORDER_PASSENGER_CANCEL:
            case OrderEvent.ORDER_CLOSE:
            case OrderEvent.ORDER_MATCH_THE_TIMEOVER:
            case OrderEvent.ORDER_HAS_BEEN_ROBBED:
                if (event.obj1 == null) return;
                if (!isOnDuty) return;
                SocketPushContent push = (SocketPushContent) event.obj1;
                for (int i = 0; i < mOrderList.size(); i++) {
                    if (push.orderUuid.equals(mOrderList.get(i).orderUuid)) {
                        mOrderList.remove(i);
                    }
                }
                break;
            case OrderEvent.IGNORE_ORDER:
                if (event.obj1 == null) return;
                if (!isOnDuty) return;
                String orderUuid = (String) event.obj1;
                for (int i = 0; i < mOrderList.size(); i++) {
                    if (orderUuid.equals(mOrderList.get(i).orderUuid)) {
                        mOrderList.remove(i);
                    }
                }
                break;
            case OrderEvent.ORDER_COMPLETE:
                if (event.obj1 == null) return;
                isComplete = (boolean) event.obj1;
                break;
        }
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    public void onNetworkEvent(NetworkEvent event) {
        switch (event.type) {
            case NetworkEvent.CONNECT:
                mView.showNetwork(true);
                break;
            case NetworkEvent.DISCONNECT:
                mView.showNetwork(false);
                break;
            case NetworkEvent.LOCATION_SUCCESS:
                mView.showLocation(true);
                break;
            case NetworkEvent.LOCATION_FAILED:
                mView.showLocation(false);
                break;
            case NetworkEvent.SOCKET_SUCCESS:
                mView.showSocket(true);
                break;
            case NetworkEvent.SOCKET_FAILED:
                mView.showSocket(false);
                break;
            case NetworkEvent.UPLOAD_SUCCESS:
                if (mSubscribe != null && !mSubscribe.isUnsubscribed()) {
                    mSubscribe.unsubscribe();
                }
                onDuty();
                break;
        }
    }
}
